package com.jichaoyun.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jichaoyun.common.model.Result;
import com.jichaoyun.common.enums.MyExceptiontType;
import com.jichaoyun.common.ex.MyException;
import com.jichaoyun.dao.mapper.*;
import com.jichaoyun.model.entity.LineInfo;
import com.jichaoyun.model.vo.FlowVo;
import com.jichaoyun.service.IStationInfoService;
import com.jichaoyun.service.LineInfoService;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ljc
 * @description 针对表【lineInfo】的数据库操作Service实现
 * @createDate 2023-11-18 16:26:25
 */
@Service
@Slf4j
public class LineInfoServiceImpl extends ServiceImpl<LineInfoMapper, LineInfo>
        implements LineInfoService {

    @Autowired
    private LineInfoMapper lineInfoMapper;

    @Autowired
    private FlowDayMapper flowDayMapper;

    @Autowired
    private FlowMonthMapper flowMonthMapper;

    @Autowired
    private IStationInfoService stationInfoService;

    @Autowired
    private StationInfoMapper stationInfoMapper;


    @Autowired
    private PowerAlarmMapper poweralarmMapper;


    /**
     * 新增线路
     * @param lineInfo
     * @return
     */
    @Override
    public Result<Object> addLineInfo(LineInfo lineInfo) {

        if (lineInfo.getLineName().isEmpty()) {
            throw new MyException(MyExceptiontType.Other,"线路名称不能为空");
        }
        LambdaQueryWrapper<LineInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LineInfo::getLineName, lineInfo.getLineName())
                .or()
                .eq(LineInfo::getLineAlias,lineInfo.getLineName());

        LineInfo lineInfo1 = this.lineInfoMapper.selectOne(queryWrapper);
        if (lineInfo1 != null) {
            throw new MyException(MyExceptiontType.STATIONALIASDUPLITE,"线路名称已存在");
        }

        if(!Objects.equals(lineInfo.getLineAlias(), "")){
            LambdaQueryWrapper<LineInfo> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(LineInfo::getLineName,lineInfo.getLineAlias())
                    .or()
                    .eq(LineInfo::getLineAlias,lineInfo.getLineAlias());

            LineInfo lineInfo2 = this.lineInfoMapper.selectOne(queryWrapper1);
            if (lineInfo2 != null) {
                throw new MyException(MyExceptiontType.STATIONALIASDUPLITE,"线路别名已存在");
            }
        }

        lineInfoMapper.insert(lineInfo);
        return Result.success("增加线路成功");
    }

    /**
     * 更改线路别名
     * @param lineInfo
     */
    @Override
    public Result<Object> updateLineAlias(LineInfo lineInfo) { // id : 8 name : 线路k  alias:333
        if (!lineInfo.getLineAlias().isEmpty()) {
            LambdaQueryWrapper<LineInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LineInfo::getLineAlias, lineInfo.getLineAlias())
                        .or()
                        .eq(LineInfo::getLineName,lineInfo.getLineAlias());
            LineInfo lineInfo1 = this.lineInfoMapper.selectOne(queryWrapper);
            if (lineInfo1 != null && lineInfo1.getLineNum() != lineInfo.getLineNum()) {
//                throw new MyException(MyExceptiontType.STATIONALIASDUPLITE, "线路别名已存在");
                return Result.fail(lineInfo.getLineName() + "  线路别名已存在");
            }
        }
        lineInfoMapper.updateById(lineInfo);
//        log.info(lineInfo.getLineName() + " update alias " + lineInfo.getLineAlias());
        return Result.success("修改成功");
    }

    /**
     * 批量更改线路别名
     * @param lineInfos
     */
    public Result<Object> updateLineAliasBatch(List<LineInfo> lineInfos) {
        for (LineInfo lineInfo : lineInfos) {
            Result res = updateLineAlias(lineInfo);
            if(!res.getMessage().equals("修改成功")){
                return updateLineAlias(lineInfo);
            }
        }
        return Result.success("修改成功");
    }

    /**
     * 获取线路列表
     * @return
     */
    @Override
    public List<LineInfo> getLineList() {
        QueryWrapper<LineInfo> wrapper = new QueryWrapper<>();
        wrapper.select("line_num,line_name,line_alias");
        return this.lineInfoMapper.selectList(wrapper);
    }

    public String longToDate(Long datetime) {
        Date date = new Date(datetime * 1000);
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sd.format(date);
    }

    //查询某天 所有 站点及流量
    private List<FlowVo> Inquire(String start_time, String end_time) {
//        LambdaQueryWrapper<FlowDay> wrapper = new LambdaQueryWrapper<>();
//        wrapper.le(FlowDay::getRecStart, end_time).ge(FlowDay::getRecStart, start_time).isNotNull(FlowDay::getFTotalStart);
//        return flowDayMapper.selectList(wrapper);
        return flowDayMapper.selectFlowdayList(start_time,end_time);
    }

    /**
     * 获取各线路当日流量分布
     * @return
     */
    @Override
    public Map<String, Float> getLineFlowDay() {
        Map<String, Float> map = new HashMap<>();
        LocalDateTime today_start = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        List<FlowVo> result = Inquire(df.format(today_start.minusDays(2)), df.format(today_start.minusDays(1)));
        if (result.isEmpty()) {
            throw new MyException(MyExceptiontType.Other, null);
        }

        for (FlowVo item : result) {
            String key = item.getLineName();
            Float end = 0F, begin = 0F;
            if (item.getFTotalStart() == null) begin = 0F;
            else begin = item.getFTotalStart();
            if (item.getFTotalEnd() == null) end = 0F;
            else end = item.getFTotalEnd();
            if (!map.containsKey(key)) {
                map.put(key, end - begin);
            } else {
                Float cnt = map.get(key);
                map.put(key, cnt + end - begin);
            }
        }
        return map;
    }

    private List<FlowVo> Inquire_month(String start_time, String end_time) {
//        LambdaQueryWrapper<FlowMonth> wrapper = new LambdaQueryWrapper<>();
//        wrapper.lt(FlowMonth::getRecStart, end_time).ge(FlowMonth::getRecStart, start_time).isNotNull(FlowMonth::getFTotalStart);
//        return flowMonthMapper.selectList(wrapper);
        return flowMonthMapper.selectFlowMonthList(start_time,end_time);
    }

    /**
     * 获取本月各线路流量分布
     * @return
     */
    @Override
    public Map<String, Float> getLineFlowMonth() {
        Map<String, Float> map = new HashMap<>();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime endDateTime = now.with(TemporalAdjusters.firstDayOfMonth()).minusMonths(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime beginDateTime = now.with(TemporalAdjusters.firstDayOfMonth()).minusMonths(2).withHour(0).withMinute(0).withSecond(0);

        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        List<FlowVo> result = Inquire_month(df.format(beginDateTime), df.format(endDateTime));

        for (FlowVo item : result) {
            String key = item.getLineName();
            Float end = 0F, begin = 0F;
            if (item.getFTotalStart() == null) begin = 0F;
            else begin = item.getFTotalStart();
            if (item.getFTotalEnd() == null) end = 0F;
            else end = item.getFTotalEnd();
            if (!map.containsKey(key)) {
                map.put(key, end - begin);
            } else {
                Float cnt = map.get(key);
                map.put(key, cnt + end - begin);
            }
        }
        return map;
    }

    /**
     * 获取去年各线路流量分布
     * @return
     */
    @Override
    public Map<String, Float> getLineFlowYear() {
        Map<String, Float> map = new HashMap<>();
        LocalDateTime now = LocalDateTime.now();
        //去年的第一天
        LocalDateTime firstday = now.with(TemporalAdjusters.firstDayOfYear()).minusYears(2).withMonth(12).withHour(0).withMinute(0).withSecond(0);
        //去年的最后一天
        LocalDateTime lastDay = now.with(TemporalAdjusters.lastDayOfYear()).minusYears(1).withMonth(12).withHour(0).withMinute(0).withSecond(0);
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        List<FlowVo> result = Inquire_month(df.format(firstday), df.format(lastDay));

        for (FlowVo item : result) {
            String key = item.getLineName();

            Float end = 0F, begin = 0F;
            if (item.getFTotalStart() == null) begin = 0F;
            else begin = item.getFTotalStart();
            if (item.getFTotalEnd() == null) end = 0F;
            else end = item.getFTotalEnd();
            if (!map.containsKey(key)) {
                map.put(key, end - begin);
            } else {
                Float cnt = map.get(key);
                map.put(key, cnt + end - begin);
            }
        }
        return map;
    }

    /**
     * 获取昨日流量排名
     * @return
     */
    @Override
    public Map<String, Map<Float, Integer>> getDayFlowRank() {
        Map<String, Float> yesterday = new HashMap<>();
        Map<String, Float> today = new HashMap<>();

        LocalDateTime today_start = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LinkedHashMap<String, Map<Float, Integer>> res = new LinkedHashMap<>();
        List<FlowVo> result_yes = Inquire(df.format(today_start.minusDays(3)), df.format(today_start.minusDays(2)));
        List<FlowVo> result_to = Inquire(df.format(today_start.minusDays(2)), df.format(today_start.minusDays(1)));

        if (!result_yes.isEmpty()) {
            for (FlowVo item : result_yes) {
                Float end = 0F, begin = 0F;
                if (item.getFTotalStart() == null) begin = 0F;
                else begin = item.getFTotalStart();
                if (item.getFTotalEnd() == null) end = 0F;
                else end = item.getFTotalEnd();
                yesterday.put(item.getStationName(), end - begin);
            }
        }

        if (result_to.isEmpty()) throw new MyException(MyExceptiontType.Other, null);
        for (FlowVo item : result_to) {
            Float end = 0F, begin = 0F;
            if (item.getFTotalStart() == null) begin = 0F;
            else begin = item.getFTotalStart();
            if (item.getFTotalEnd() == null) end = 0F;
            else end = item.getFTotalEnd();
            today.put(item.getStationName(), end - begin);
        }
        //对today按value从大到小排序
        Map<String, Float> resultMap1 = today.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (s, s2) -> s, LinkedHashMap::new));

        int i = 10;
        for (String key : resultMap1.keySet()) {
            if (i > 0) {
                Map<Float, Integer> map = new HashMap<>();
                int t = 0;
                if (yesterday.containsKey(key) && today.containsKey(key)) {
                    if (today.get(key) > yesterday.get(key)) t = 1;
                    else if (today.get(key) < yesterday.get(key)) t = -1;
                } else if (today.containsKey(key)) {
                    t = 1;
                }
                map.put(today.get(key), t);
                res.put(key, map);
            } else {
                break;
            }
            i--;
        }
        return res;
    }

    /**
     * 获取上月流量排名
     * @return
     */
    @Override
    public Map<String, Map<Float, Integer>> getMonthFlowRank() {
        Map<String, Float> lastMonth = new HashMap<>();
        Map<String, Float> thisMonth = new HashMap<>();

        LocalDateTime now = LocalDateTime.now();
        LocalDateTime endDateTime = now.with(TemporalAdjusters.firstDayOfMonth()).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime beginDateTime = now.with(TemporalAdjusters.firstDayOfMonth()).minusMonths(1).withHour(0).withMinute(0).withSecond(0);

        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LinkedHashMap<String, Map<Float, Integer>> res = new LinkedHashMap<>();
        List<FlowVo> result_last = Inquire_month(df.format(beginDateTime.minusMonths(2)), df.format(endDateTime.minusMonths(2)));
        List<FlowVo> result_this = Inquire_month(df.format(beginDateTime.minusMonths(1)), df.format(endDateTime.minusMonths(1)));

        for (FlowVo item : result_last) {
            Float end = 0F, begin = 0F;
            if (item.getFTotalStart() == null) begin = 0F;
            else begin = item.getFTotalStart();
            if (item.getFTotalEnd() == null) end = 0F;
            else end = item.getFTotalEnd();
            lastMonth.put(item.getStationName(), end - begin);
        }
        for (FlowVo item : result_this) {
            Float end = 0F, begin = 0F;
            if (item.getFTotalStart() == null) begin = 0F;
            else begin = item.getFTotalStart();
            if (item.getFTotalEnd() == null) end = 0F;
            else end = item.getFTotalEnd();
            thisMonth.put(item.getStationName(), end - begin);
        }
        //对thisMonth按value从大到小排序
        Map<String, Float> resultMap1 = thisMonth.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (s, s2) -> s, LinkedHashMap::new));

        int i = 10;
        for (String key : resultMap1.keySet()) {
            if (i > 0) {
                Map<Float, Integer> map = new HashMap<>();
                int t = 0;
                if (lastMonth.containsKey(key) && thisMonth.containsKey(key)) {
                    if (thisMonth.get(key) > lastMonth.get(key)) t = 1;
                    else if (thisMonth.get(key) < lastMonth.get(key)) t = -1;
                } else if (thisMonth.containsKey(key)) {
                    t = 1;
                }
                map.put(thisMonth.get(key), t);
                res.put(key, map);
            } else {
                break;
            }
            i--;
        }
        return res;
    }

    /**
     * 获取去年流量排名
     * @return
     */
    @Override
    public Map<String, Map<Float, Integer>> getYearFlowRank() {
        Map<String, Float> lastYear = new HashMap<>();
        Map<String, Float> thisYear = new HashMap<>();

        LinkedHashMap<String, Map<Float, Integer>> res = new LinkedHashMap<>();
        LocalDateTime now = LocalDateTime.now();
        //去年的第一天
        LocalDateTime firstday = now.with(TemporalAdjusters.firstDayOfYear()).minusYears(1).withHour(0).withMinute(0).withSecond(0);
        //去年的最后一天
        LocalDateTime lastDay = now.with(TemporalAdjusters.lastDayOfYear()).minusYears(1).withHour(23).withMinute(59).withSecond(59);
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        List<FlowVo> result_last = Inquire_month(df.format(firstday.minusYears(1)), df.format(lastDay.minusYears(1)));
        List<FlowVo> result_this = Inquire_month(df.format(firstday), df.format(lastDay));

        for (FlowVo item : result_last) {
            String key = item.getStationName();

            Float end = 0F, begin = 0F;
            if (item.getFTotalStart() == null) begin = 0F;
            else begin = item.getFTotalStart();
            if (item.getFTotalEnd() == null) end = 0F;
            else end = item.getFTotalEnd();
            if (!lastYear.containsKey(key)) {
                lastYear.put(key, end - begin);
            } else {
                Float cnt = lastYear.get(item.getStationName());
                lastYear.put(key, cnt + end - begin);
            }
        }

        for (FlowVo item : result_this) {
            String key = item.getStationName();

            Float end = 0F, begin = 0F;
            if (item.getFTotalStart() == null) begin = 0F;
            else begin = item.getFTotalStart();
            if (item.getFTotalEnd() == null) end = 0F;
            else end = item.getFTotalEnd();
            if (!thisYear.containsKey(key)) {
                thisYear.put(key, end - begin);
            } else {
                Float cnt = thisYear.get(key);
                thisYear.put(key, cnt + end - begin);
            }
        }
        //对thisYear按value从大到小排序
        Map<String, Float> resultMap1 = thisYear.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (s, s2) -> s, LinkedHashMap::new));

        int i = 10;
        for (String key : resultMap1.keySet()) {
            if (i > 0) {
                Map<Float, Integer> map = new HashMap<>();
                int t = 0;
                if (lastYear.containsKey(key) && thisYear.containsKey(key)) {
                    if (thisYear.get(key) > lastYear.get(key)) t = 1;
                    else if (thisYear.get(key) < lastYear.get(key)) t = -1;
                } else if (thisYear.containsKey(key)) {
                    t = 1;
                }
                map.put(thisYear.get(key), t);
                res.put(key, map);
            } else {
                break;
            }
            i--;
        }
        return res;
    }

    private String getNextDay(String dateTime) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date datetime = null;
        try {
            datetime = simpleDateFormat.parse(dateTime);
        } catch (ParseException e) {
            log.error("String转Date日期失败:", e);
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(datetime);
        //往后一天
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return simpleDateFormat.format(calendar.getTime());
    }


}




